//////////////////////////////////////////////////////////////////////
//                                                                  //
//                                                                  //
//              Copyright (C), 2000  SEIKO EPSON Corp.              //
//              ALL RIGHTS RESERVED                                 //
//                                                                  //
//                                                                  //
//   file name : ldexp.c                                            //
//                                                                  //
//   Revision history                                               //
//       00/02/10    first release                 M.Igarashi       //
//                                                                  //
//////////////////////////////////////////////////////////////////////

#include	<smcvals.h>
#include	<math.h>


// ALGORITHM
// 1.separate dfX into the fraction part as xfrac and into exponent part as wXexp   
// 2.caluculate exponent
//      wXexp = wXexp + dfX2
// 5.set exponent of xfrac
//
//  the architecture of double floating point
//
//   0 1          11                  31 32                               63 bit
//   -----------------------------------------------------------------------
//  | |   exponent  |                    fraction                           |
//   -----------------------------------------------------------------------
//
//               |                   |                                   |
//    12 bits          20 bits       |             32 bits               |
//            lower word             |            higher word            |
//
//         bit    0         sign bit         (  1 bit  )
//              1 - 11      exponent part    ( 11 bits )
//             12 - 63      fraction part    ( 52 bits )
//
//
 
double ldexp (double dfX, int dfX2){

	DBL_LNG	xfrac;
	unsigned long	ulHi;
	double dfRet;
	signed short	wXexp;


	xfrac._D=dfX;
	ulHi=xfrac.st._LL;

	wXexp=GET_EXP(ulHi)+dfX2;
	if((dfX2>2*B_DBL)||(wXexp > MAX_E)){
		errno	= ERANGE;
		if((ulHi&0x80000000) !=0){		//check arg
			dfRet=N_INF._D;
		}else{
			dfRet=P_INF._D;
		}
		return dfRet;
	}
	if ( wXexp < MIN_E ){				// too small
		dfRet=COPY_SIGN(0.0,dfX);
		return dfRet;
	}

	ulHi=EXP_PUT(MASK_EXPO(ulHi),wXexp);		// put expo
	xfrac.st._LL=ulHi;
	dfRet=xfrac._D;
	return dfRet;
}
